Developer Documentation

QuickTime 4 API Documentation

QuickTime 4 Reference

Previous | Chapter Top | Chapter Contents | Next |

Playing Piano Sounds with the Note Allocator

The routine in Listing 2 plays notes in a piano sound with the note allocator component. You start by calling OpenDefaultComponent to open a connection to the note allocator. If this routine returns 0, the component wasn't opened, most likely because QTMA wasn't present.

Listing 2 Playing notes with the note allocator component

void PlaySomeNotes(void)
{
    NoteAllocator na;
    NoteChannel nc;
    NoteRequest nr;
    ComponentResult thisError;
    long t, i;

    na = 0;
    nc = 0;

    // * Open up the note allocator.
    na = OpenDefaultComponent(kNoteAllocatorType, 0);
    if (!na)
        goto goHome;

    // * Fill out a NoteRequest using NAStuffToneDescription to help, and
    // * allocate a NoteChannel.
    nr.info.flags = 0;
    nr.info.reserved = 0;
    nr.info.polyphony = 2; // * simultaneous tones
    nr.info.typicalPolyphony = 0x00010000; // * usually just one note
    thisError = NAStuffToneDescription(na, 1, &nr.tone); // * 1 is piano
    thisError = NANewNoteChannel(na, &nr, &nc);
    if (thisError || !nc)
        goto goHome;

    // * If we've gotten this far, OK to play some musical notes. Lovely.
    NAPlayNote(na, nc, 60, 80); // * middle C at velocity 80
    Delay(40, &t); // * delay 2/3 of a second
    NAPlayNote(na, nc, 60, 0); // * middle C at velocity 0: end note
    Delay(40, &t); // * delay 2/3 of a second

    // * Obligatory do-loop of rising tones
    for (i = 60; i <= 84; i++) {
        NAPlayNote(na, nc, i, 80); // * pitch i at velocity 80
        NAPlayNote(na, nc, i+7, 80); // * pitch i+7 (musical fifth) at
                                        // * velocity 80
        Delay(10, &t); // * delay 1/6 of a second
        NAPlayNote(na, nc, i, 0); // * pitch i at velocity 0: end note
        NAPlayNote(na, nc, i+7, 0); // * pitch i+7 at velocity 0:
                                        // * end note
    }

goHome:
    if (nc)
        NADisposeNoteChannel(na, nc);
    if (na)
        CloseComponent(na);
}

Next, you fill in the NoteRequestInfo and ToneDescription structures, calling the note allocator's NAStuffToneDescription routine and passing it the GM instrument number for piano. This routine fills in the gmNumber field and also fills in the other ToneDescription fields with sensible values, such as the instrument's name in text form in the instrumentName field. (The routine can be useful for converting a GM instrument number to its text equivalent.)

After allocating the note channel with NANewNoteChannel , you call NAPlayNote to play each note. Notice the last two parameters to NAPlayNote :

ComponentResult NAPlayNote(NoteAllocator na, NoteChannel nc,
    long pitch, long velocity);

The value of the pitch parameter is an integer from 1 to 127, where 60 is middle C, 61 is C sharp, and 59 is C flat, or B. Similarly, 69 is concert A, and is played at a nominal audio frequency of 440 Hz.

The velocity parameter's value is also an integer from 1 to 127, or 0. A velocity of 1 corresponds to just barely touching the musical keyboard, and 127 indicates that the key was struck as hard as possible. Different velocities produce tones of different volumes from the synthesizer. A velocity of 0 means the key was released; the note stops or fades out, as appropriate to the kind of sound being played.

You stop the notes at this point after delaying an appropriate amount of time with a call to the Delay routine. Finally, you dispose of the note channel and close the note allocator component.

 

© 1999 Apple Computer, Inc.

Previous | Chapter Top | Chapter Contents | Next